<!--  -->
<template>
    <div id="container" style="height:100%;width: 100%;"></div>

</template>

<script setup lang="ts">
import {
    Scene,
    PerspectiveCamera,
    BoxGeometry,
    MeshBasicMaterial,
    MeshNormalMaterial,
    Mesh,
    WebGLRenderer,
    AxesHelper,
    BufferGeometry,
    BufferAttribute,
    TextureLoader,
    AmbientLight,
    SpotLight,
    Float32BufferAttribute,
    PointLight,
    LineBasicMaterial,
    Color,
    Vector3,
    Line,
    LinePieces,
    VertexColors,
    DoubleSide,
    MeshPhongMaterial,
    RepeatWrapping,
    NearestFilter,
    PlaneGeometry,
    HemisphereLight,
    PointLightHelper,
    SphereGeometry,
    AnimationMixer,
    LoopOnce,
    Clock,
    DirectionalLight
} from 'three'
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader';
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader';
// 导入轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import gsap from "gsap";//动画库
import { onMounted } from 'vue';
import * as dat from "dat.gui";

let scene: any = null;
let camera: any = null;
let mesh: any = null;
let renderer: any = null;
let point: any = null;
let yUP = false;
let mixer: any = null;
let action : any = null;
const clock = new Clock();
onMounted(() => {
    init();
    animate();
    activationGsap();
    upWindowAddEventListener();
    // datGui();
    // threeBufferGeometry();
    loaderObj();
    
})

const init = () => {
    let container = document.getElementById('container');
    if (!container) {
        return;
    }

    // 创建场景
    scene = new Scene();
    // 创建相机
    camera = new PerspectiveCamera(120, container.clientWidth / container.clientHeight, 1, 1000);

    // 设置相机位置
    camera.position.set(0, 10, 15);
    scene.add(camera);


    // 地面 平铺
    const planeSize = 20
    const loader = new TextureLoader()
    const texturePlan = loader.load('https://threejs.org/manual/examples/resources/images/checker.png')
    // THREE.RepeatWrapping 纹理重复
    texturePlan.wrapS = RepeatWrapping
    texturePlan.wrapT = RepeatWrapping
    // 当一个纹素覆盖大于一个像素时，贴图将如何采样。 THREE.NearestFilter，它将使用最接近的纹素的值。
    texturePlan.magFilter = NearestFilter
    const repeats = planeSize / 2
    // 重复次数
    texturePlan.repeat.set(repeats, repeats)
    const planeGeo = new PlaneGeometry(planeSize, planeSize)
    // Phong材质
    const planeMat = new MeshPhongMaterial({ map: texturePlan, side: DoubleSide })
    const meshPlan = new Mesh(planeGeo, planeMat)
    meshPlan.rotation.x = Math.PI * -0.5
    scene.add(meshPlan)



    // 创建一个几何体
    const cubeGeometry = new SphereGeometry(2.5, 20, 20);
    // 给几何体加材质
    // const cubeMaterial = new MeshNormalMaterial();
    // 添加纹理
    const texture = new TextureLoader().load("../../public/744267.jpg");
    //给几何体加纹理
    const cubeMaterial = new MeshPhongMaterial({ map: texture, side: DoubleSide });

    mesh = new Mesh(cubeGeometry, cubeMaterial);
    mesh.position.set(2.5, 2.5, 2.5); // 位置
    // mesh.scale.y = 2; //大小
    // mesh.rotateX(Math.PI / 4);//旋转
    // mesh.rotateY(Math.PI / 4);//旋转
    // mesh.rotateZ(Math.PI / 4);//旋转
    scene.add(mesh);

    // 添加坐标系辅助器
    const axesHelper = new AxesHelper(10);
    scene.add(axesHelper);

    //环境光
    var ambient = new AmbientLight(0xffffff, 1);
    // scene.add(ambient);
    //点光源
    point = new PointLight(0xff4ae9, 1);
    point.position.set(-8, 8, 8); //点光源位置
    // 点光源距离设置为15
    point.distance = 15;
    scene.add(point); //点光源添加到场景中
    //点光源变色
    setInterval(() => {
        var hex = Math.random() * 0xffffff;
        var color = new Color(hex);
        point.color = color;
    }, 2000);

    // 方向光
    const color = 0xffffff
    const intensity = 1
    const directional = new DirectionalLight(color, intensity)
    directional.position.set(0, 15, 0)
    directional.target.position.set(-5, 0, 0)
    // scene.add(directional)
    // scene.add(directional.target)

    // 光源辅助线
    const helper = new PointLightHelper(point);
    scene.add(helper)
    //半球光
    const hemisphere = new HemisphereLight(0xb1e1ff, 0xffffff, 1)
    scene.add(hemisphere)

    // 初始化渲染器
    renderer = new WebGLRenderer();
    renderer.setClearColor(0x66ffcc, 1); //设置背景颜色
    // 设置渲染器的尺寸
    renderer.setSize(container.clientWidth, container.clientHeight);
    // 将webgl渲染的东西放到body上
    container.appendChild(renderer.domElement);

    // 创建轨道控制器
    const controls = new OrbitControls(camera, renderer.domElement);
}
const animate = () => {
    renderer.render(scene, camera);
 
    // if (mesh.position.y >= 7.5) {
    //     yUP = false;
    // }
    // if (mesh.position.y <= 2.5) {
    //     yUP = true;
    // }

    // if (yUP) {
    //     mesh.position.y += 0.1;
    // } else {
    //     mesh.position.y -= 0.2;
    // }

    // mesh.rotation.y += 0.02;
    // camera.rotation.x += 0.01;
    // camera.rotation.y += 0.02;
    const time = clock.getDelta();
    if (mixer) {
        mixer.update(time);
    }

    requestAnimationFrame(animate);
}
//动画
const activationGsap = () => {
    let animate = gsap.to(mesh.position, {
        y: 7.5,
        duration: 1,
        ease: "power1.inOut",
        // 设置重复次数 -1无限次
        repeat: -1,
        // 往返运动
        yoyo: true,
        // 延迟动画
        delay: 0,
        onComplete: () => {
            console.log("动画完成了");
        },
        onStart: () => {
            console.log("动画开始了");
        },
    });
    window.addEventListener("dblclick", () => {
        if (animate.isActive()) {
            animate.pause();
        } else {
            animate.resume();
        }
    });
}
//自适应画面
const upWindowAddEventListener = () => {

    window.addEventListener("resize", () => {
        let container = document.getElementById('container');
        if (!container) {
            return;
        }
        // 更新摄像头
        camera.aspect = container.clientWidth / container.clientHeight;
        // 更新摄像头的投影矩阵
        camera.updateProjectionMatrix();
        // 更新渲染器
        renderer.setSize(container.clientWidth, container.clientHeight);
        // 设计渲染器的像素比
        renderer.setPixelRatio(window.devicePixelRatio);
        // 将webgl渲染的东西放到body上
        container.appendChild(renderer.domElement);
    });
}
const datGui = () => {
    const gui = new dat.GUI();
    // 移动
    gui.add(mesh.position, "x").min(0).max(5).step(0.01).name("移动x轴");
    // 修改颜色
    const params = {
        color: "#ffff00",
    };
    gui
        .addColor(params, "color")
        .name("修改颜色")
        .onChange((value: string) => {
            mesh.material.color.set(value);
        });
    // 设置选项框
    gui.add(mesh, "visible").name("是否显示");
    // 设置立方体
    const folder = gui.addFolder("设置立方体");
    folder.add(mesh.material, "wireframe");
}
const threeBufferGeometry = () => {
    const geometry = new BufferGeometry();
    // 创建一个简单的矩形. 在这里我们左上和右下顶点被复制了两次。
    // 因为在两个三角面片里，这两个顶点都需要被用到。
    const vertices = new Float32Array([
        0, 0, 0,
        2, 0, 0,
        2, 2, 0,

        2, 2, 0,
        0, 2, 0,
        0, 0, 0
    ]);

    var uvs = new Float32Array([
        0, 0, //图片左下角
        1, 0, //图片右下角
        1, 1, //图片右上角
        0, 1, //图片左上角
    ]);

    const texture = new TextureLoader().load("../../public/744267.jpg");
    // itemSize = 3 因为每个顶点都是一个三元组。
    geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
    // 设置几何体attributes属性的位置normal属性
    geometry.setAttribute('uv', new BufferAttribute(uvs, 2));
    const material = new MeshBasicMaterial({ map: texture });
    const mesh_m = new Mesh(geometry, material);

    scene.add(mesh_m);
}

const loaderObj = () => {
    const mtlLoader = new MTLLoader();
    mtlLoader.load('../../public/Tree/Tree.mtl', (mtl: any) => {
        mtl.preload();
        console.log('mtl', mtl)

        const loader = new GLTFLoader();
        // loader.setMaterials(mtl);
        loader.load('../../public/Tree/TreeGltf.gltf', (obj: any) => {
            console.log(obj);
            obj.scene.position.x = -3;
            scene.add(obj.scene);
        });

        const fbx = new FBXLoader();
        fbx.load('../../public/Fall-Flat.fbx', (fbx2: any) => {
            fbx2.scale.x = 0.03;
            fbx2.scale.y = 0.03;
            fbx2.scale.z = 0.03;
            fbx2.position.z = 7;
            scene.add(fbx2);
            mixer = new AnimationMixer( fbx2 );
            action = mixer.clipAction(fbx2.animations[0])//把该物体需要的动画拿出来

            action.play();
        });
    });
}


</script>
<style lang='less' scoped>
</style>
